package cn.lyjuan.payment.third.base.pay.chl.impl.weixin;

import cn.lyjuan.base.util.SpringUtils;
import cn.lyjuan.payment.third.base.pay.chl.impl.AbstractPayChl;
import cn.lyjuan.payment.third.base.pay.chl.impl.weixin.bean.*;
import cn.lyjuan.payment.third.base.pay.chl.impl.weixin.util.*;
import cn.lyjuan.payment.third.base.pay.cst.PayConst;
import cn.lyjuan.payment.third.base.pay.enums.SimpleChlEnum;
import cn.lyjuan.payment.third.base.pay.enums.SimpleStatusEnum;
import cn.lyjuan.payment.third.base.pay.vo.req.NotifyReq;
import cn.lyjuan.payment.third.base.pay.vo.req.PayReq;
import cn.lyjuan.payment.third.base.pay.vo.req.QueryReq;
import cn.lyjuan.payment.third.base.pay.vo.req.TransferReq;
import cn.lyjuan.payment.third.base.pay.vo.res.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 微信公众号支付渠道
 */
@Slf4j
@Component
public class WxpayMPChlImpl extends AbstractPayChl<WxChlCnf, WxPayReq, WxNotifyReq, WxQueryReq, WxTransferReq, WxPayRes> {

    @Autowired
    private PayConst payConst;

    @Override
    public SimpleChlEnum chl() {
        return SimpleChlEnum.WX_MP;
    }

    @Override
    public BaseRes checkPayParams(WxPayReq params) {
        // 不需要额外参数
        return new BaseRes();
    }

    @Override
    public BaseRes checkTransferParams(WxTransferReq params) {
        return WxpaySubmit.checkTransferReq(params);
    }

    @Override
    public WxQueryReq parseQueryParams(Map<String, String> params) {
        return null;
    }

    @Override
    public WxNotifyReq parseNotifyParams(HttpServletRequest req) {
        String body = SpringUtils.reqBody(req);
        Map<String, String> resultMap = WxpayNotify.parseNotifyData(body);
        WxNotifyReq params = new WxNotifyReq();
        params.putAll(resultMap);
        return params;
    }

    @Override
    public PayRes<WxPayRes> order(PayReq<WxPayReq> req, WxChlCnf cnf) {
        PayRes<WxPayRes> res;
//        if (req.getParams().getTradeType().equals(WxTradeType.WEB_QRCODE)) {
//            res = WxpaySubmit.unifiedOrder(req, cnf, 8000, 10000, chl(), payConst.isDev());
//            if (res == null) {
//                res = new PayRes<>(false, "wechat handler request error");
//            }
//        } else {
//        }
        // 微信支付授权
        String authTradeXml = WxpaySubmit.createTradeAuth(req, cnf);

        // 发送授权请求
        Map<String, String> params = WxpaySubmit.sendTradeAuth(authTradeXml);

        // 封闭交易信息
        res = WxpaySubmit.createTradeExec(req, cnf, params);
        return res;
    }

    @Override
    public TransferRes<WxPayRes> transfer(TransferReq<WxTransferReq> req, WxChlCnf cnf) {
        TransferRes<WxPayRes> res = WxpaySubmit.transferExec(req, cnf, chl());
        return res;
    }

    @Override
    public NotifyRes notifyStatus(NotifyReq<WxNotifyReq> req, WxChlCnf cnf) {
        // 签名验证
        boolean signMatch = WxpayNotify.veryfyNotifySign(req.getParams(), cnf);
        if (!signMatch)
            return new NotifyRes(SimpleStatusEnum.UNKNOWN, WxpayNotify.notifyRes(false));

        // 判断是否成功
        SimpleStatusEnum status = WxpayNotify.parseNotifyPayStatus(req.getParams());

        if (SimpleStatusEnum.SUCC == status)
            return new NotifyRes(status, WxpayNotify.notifyRes(true));

        String msg = WxpayNotify.notifyErrorMsg(req.getParams());

        String tranNo = WxpayNotify.parseTranNoFromNotify(req.getParams());
        return new NotifyRes(status, msg, tranNo, WxpayNotify.notifyRes(true));
    }

    @Override
    public QueryRes queryStatus(QueryReq<WxQueryReq> req, WxChlCnf cnf) {
        // 组装支付结果查询XML
        String tradeQueryXml = WxpayQuery.createTradeQuery(req, cnf);

        // 发送查询请求
        Map<String, String> result = WxpayQuery.sendTradeQuery(tradeQueryXml);

        // 交易状态
        SimpleStatusEnum status = WxpayNotify.parseNotifyPayStatus(result);
        // 支付平台状态描述
        String chlMsg = WxpayNotify.notifyErrorMsg(result);
        // 支付平台交易号
        String tranNo = WxpayNotify.parseTranNoFromNotify(result);

        return new QueryRes(status, chlMsg, tranNo, null);
    }

    @Override
    public RefundRes orderRefund(String selfRefundNo, String localNo, Integer totalAmt, Integer amt, WxChlCnf cnf) {
        // 组装退款XML
        String tradeRefundXml = WxpayRefund.createTradeAuth(selfRefundNo, localNo, totalAmt, amt, cnf);
        // 发送请求
        String result = RefundRequest.httpsRequest(WxpayRefund.REFUND_URL, tradeRefundXml, cnf.getMchId(), cnf.getCertPath());
        // 解析响应
        Map<String, String> params = WxpayRefund.parseAuthTradeRes(result);
        // 封闭信息
        RefundRes res = WxpayRefund.convertResponseToRefundRes(localNo, cnf, params);
        return res;
    }
}
